package wx

import (
	"context"
	"fmt"
	"net/http"

	"github.com/wechatpay-apiv3/wechatpay-go/core"
	"github.com/wechatpay-apiv3/wechatpay-go/core/auth/verifiers"
	"github.com/wechatpay-apiv3/wechatpay-go/core/downloader"
	"github.com/wechatpay-apiv3/wechatpay-go/core/notify"

	"github.com/wechatpay-apiv3/wechatpay-go/core/option"
	"github.com/wechatpay-apiv3/wechatpay-go/services/payments"
	app "github.com/wechatpay-apiv3/wechatpay-go/services/payments/app"
	"github.com/wechatpay-apiv3/wechatpay-go/utils"
)

var (
	// appid
	appid = "com.shouyizige.app"
	// 商户号  在微信支付商户平台注册后获得的唯一标识符。
	mchID = "1628502877"
	// APIv3密钥 在微信支付商户平台生成APIv3密钥，用于加密和解密敏感信息。
	APIv3Key = "7c5vjF3yw8K9z1xP5B3Q7rG6W1n2mL8p"
	// api私钥路径, 在申请API证书时，你会得到一个私钥文件（通常为apiclient_key.pem）
	privateKeyPath = "./wx/apiclient_key.pem"
	// 证书序列号 在你申请微信支付商户API证书后，每个证书都会有一个唯一的序列号。
	CertificateSN = "2C88FB75600F18872EBBB1335EBCCD3703ECC38E"
)

var appService app.AppApiService
var notfHandle *notify.Handler

// 测试阶段 参数使用固定参数
func Init() error {

	ctx := context.Background()

	// 加载api私钥
	mchPrivateKey, err := utils.LoadPrivateKeyWithPath(privateKeyPath)
	if err != nil {
		return fmt.Errorf("加载微信支付api私钥失败: %v", err)
	}

	// 初始化微信支付client
	opts := []core.ClientOption{
		option.WithWechatPayAutoAuthCipher(mchID, CertificateSN, mchPrivateKey, APIv3Key),
	}

	client, err := core.NewClient(ctx, opts...)
	if err != nil {
		return fmt.Errorf("创建微信支付客户端失败: %v", err)
	}

	if err := downloader.MgrInstance().RegisterDownloaderWithClient(ctx, client, mchID, APIv3Key); err != nil {
		return fmt.Errorf("创建微信支付证书下载器失败:%v", err)
	}

	// 获取商户的平台证书访问器
	certificateVisitor := downloader.MgrInstance().GetCertificateVisitor(mchID)

	// 使用平台证书提供器生成SHA256WithRSA类型的数字签名验证器
	notfHandle = notify.NewNotifyHandler(APIv3Key, verifiers.NewSHA256WithRSAVerifier(certificateVisitor))
	appService = app.AppApiService{Client: client}

	return nil
}

/*
商品描述desc  order表
订单orderId   order表
价格price     order表
*/
func MakePrePayId(ctx context.Context, desc string, orderId string, price int64) (resp *app.PrepayResponse, result *core.APIResult, err error) {
	request := app.PrepayRequest{
		Appid:       core.String(appid), // 公众号或小程序ID
		Mchid:       core.String(mchID),
		Description: core.String(desc),
		OutTradeNo:  core.String(orderId),
		Amount: &app.Amount{
			Total: core.Int64(price), // 单位为分
		},
	}
	return appService.Prepay(ctx, request)
}

// 微信支付关闭预支付
func CloseOrder(ctx context.Context, outTradeNo string) (result *core.APIResult, err error) {
	req := app.CloseOrderRequest{
		Mchid:      core.String(mchID),      // 商户号
		OutTradeNo: core.String(outTradeNo), // 商户订单号
	}

	return appService.CloseOrder(ctx, req)
}

// TransactionId 微信支付订单号
func QueryOrderByTransactionId(ctx context.Context, transactionId string) (resp *payments.Transaction, result *core.APIResult, err error) {
	req := app.QueryOrderByIdRequest{
		TransactionId: core.String(transactionId),
		Mchid:         core.String(mchID),
	}

	return appService.QueryOrderById(ctx, req)
}

// 通过商户订单号查询
func QueryOrderByOutTradeNo(ctx context.Context, outTradeNo string) (resp *payments.Transaction, result *core.APIResult, err error) {
	req := app.QueryOrderByOutTradeNoRequest{
		OutTradeNo: core.String(outTradeNo),
		Mchid:      core.String(mchID),
	}
	return appService.QueryOrderByOutTradeNo(ctx, req)
}

// 微信支付回调通知(内容解析)
func HandleNotification(ctx context.Context, req *http.Request, content interface{}) (*notify.Request, error) {
	return notfHandle.ParseNotifyRequest(ctx, req, content)
}
